package com.qdlc.p2p.common.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.Security;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import com.google.gson.Gson;
import com.qdlc.p2p.common.core.PropertyPlaceholderConfigurerHelper;

/**
 * 发送邮件
 *
 * @author wuaj
 */
public class MailUtil implements Runnable {
    private static ExecutorService mailPool = Executors.newFixedThreadPool(2);

    private static String DEFAULT_TITLE = "酒掌柜理财";

    private static Gson gson = new Gson();

    private String group;

    private String title;

    private Object content;

    private String url;

    public MailUtil(String group, String title, Object content, String url) {
        this.group = group;
        this.title = title;
        this.content = content;
        this.url = url;
    }

    public static void sendMail(Object content) {
        sendMail("default", DEFAULT_TITLE, content, null);
    }

    public static void sendMail(String title, Object content) {
        sendMail("default", title, content, null);
    }

    public static void sendMail(Object content, String url) {
        sendMail("default", DEFAULT_TITLE, content, url);
    }

    public static void sendMail(String title, Object content, String url) {
        sendMail("default", title, content, url);
    }

    public static void sendMail(String group, String title, Object content, String url) {
        mailPool.submit(new MailUtil(group, title, content, url));
    }

    @Override
    public void run() {
        try {
            if (content == null || StringUtil.isEmpty(content.toString())) {
                throw new IllegalArgumentException("content is required!");
            }
            final String host = PropertyPlaceholderConfigurerHelper.getValue("mail.smtp.host");
            final String auth = PropertyPlaceholderConfigurerHelper.getValue("mail.smtp.auth");
            final String port = PropertyPlaceholderConfigurerHelper.getValue("mail.smtp.port");
            final String from = PropertyPlaceholderConfigurerHelper.getValue("mail.from");
            final String password = PropertyPlaceholderConfigurerHelper.getValue("mail.password");
            final String nick = PropertyPlaceholderConfigurerHelper.getValue("mail.send.nick");
            final String encode = PropertyPlaceholderConfigurerHelper.getValue("mail.encode");
            final String toAddresses = PropertyPlaceholderConfigurerHelper.getValue("mail.send.to.address");
            final String ccAddresses = PropertyPlaceholderConfigurerHelper.getValue("mail.send.cc.address");
            
            Properties props = new Properties();
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.auth", auth);
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.setProperty("mail.smtp.port", port);

            Session session = Session.getDefaultInstance(props, new Authenticator() {
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(from, password);
                }
            });
            // 设置邮件发送时期
            MimeMessage message = new MimeMessage(session);
            message.setSentDate(DateUtil.getNow());
            // 设置邮件发送者的地址
            Address address = new InternetAddress(from, nick, "utf-8");
            message.setFrom(address);
            // 设置邮件发送标题
            message.setSubject(title, encode);// 设置邮件主题

            // 解析发送Group
            Map toGroupAddressMap = gson.fromJson(toAddresses, Map.class);
            Map ccGroupAddressMap = gson.fromJson(ccAddresses, Map.class);

            // 设置发送TO地址
            List<String> toAddressList = (List<String>) toGroupAddressMap.get(group);
            // 设置发送CC地址
            List<String> ccAddressList = (List<String>) ccGroupAddressMap.get(group);

            // TO地址
            Address toAddress;
            if (toAddressList != null && toAddressList.size() > 0) {
                for (String receive : toAddressList) {
                    toAddress = new InternetAddress(receive);// 设置邮件接收者的地址
                    message.addRecipient(Message.RecipientType.TO, toAddress);
                }
            }
            // CC地址
            Address ccAddress;
            if (ccAddressList != null && ccAddressList.size() > 0) {
                for (String receive : ccAddressList) {
                    ccAddress = new InternetAddress(receive);// 设置邮件接收者的地址
                    message.addRecipient(Message.RecipientType.CC, ccAddress);
                }
            }
            if (message.getAllRecipients() == null || message.getAllRecipients().length == 0) {
                throw new IllegalArgumentException("邮件发送地址 必须设定");
            }

            // 创建一个包含HTML内容的MimeBodyPart
            Multipart mainPart = new MimeMultipart();
            BodyPart html = new MimeBodyPart();
            if (content instanceof String) {
                if (StringUtil.isNotEmpty(url)) {
                    content = url + "\r\n" + content;
                }
                html.setContent(content, "text/html; charset=" + encode);
            } else if (content instanceof Exception) {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                ((Exception) content).printStackTrace(pw);//将异常信息输入到pw(PrintWriter)中
                StringBuffer sb = sw.getBuffer();
                if (StringUtil.isNotEmpty(url)) {
                    content = url + "\r\n" + sb.toString();
                } else {
                    content = sb.toString();
                }
                html.setContent(content, "text/html; charset=" + encode);
            }
            mainPart.addBodyPart(html);
            // 将MiniMultipart对象设置为邮件内容
            message.setContent(mainPart);
            Transport.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
